/*
 * Amkai Enterprise Solution (AES.) 
 * Copyright 2004 by Amkai(TM), Inc.
 * www.amkai.com
 * 
 * Project: webservice
 * Package: com.amkai.aes.webservice.binary.sourcehandler
 * File: NodeTreeHandler.java
 * Created: Oct 12, 2005 10:35:00 AM
 * Author: johnny 
 * 
 */
package com.amkai.aes.webservice.binary.objecthandler;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amkai.aes.aescommon.service.binary.job.TreeNodeJob;
import com.amkai.aes.aescommon.service.result.AvailableNodeResult;
import com.amkai.aes.aescommon.tree.rules.NodeContainRules;
import com.amkai.aes.generatedbeans.tree.Node;
import com.amkai.aes.server.domaincommiter.DomainCommitterManager;
import com.amkai.aes.server.hibernate.managment.NodeManager;
import com.amkai.aes.server.organization.NodeTreeManager;
import com.amkai.aes.server.request.DomainManager;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;
import com.amkai.rad.designerbase.beans.RADBean;

/**
 * NodeTreeHandler
 * @author johnny
 * Description:
 *
 */
public class NodeTreeHandler implements JobObjectHandler<TreeNodeJob, Serializable, Serializable> {

	
	private static final Log log = LogFactory.getLog(NodeTreeHandler.class);
	
	/**
	 * 
	 * Method: process 
	 * @param job
	 * @param object
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Serializable process(TreeNodeJob job, Serializable object) throws Exception {
		SessionManager sm = SiteManager.Start();
		NodeManager nodeManager = new NodeManager(sm);
		NodeTreeManager ntm = new NodeTreeManager(sm);
		Serializable result = null;
		try {
			sm.openSession();
			switch(job.getTreeJobKind()) {
			case GETCHILDREN:
				if (job.getNodeId() == null) {
					throw new Exception("Missing the node id, can not grant a request for node children!");
				}
				result = nodeManager.getChildrenForDummyChildren(job.getNodeId());
//				readProperty((Node)result);
				break;
			case CREATENODE:
				// KKORNEL: AES-17638 - Moved to a function #18021
				result = ntm.createNode(nodeManager, job.getNodeKind(), job.getNodeName(), job.getAcronym(), job.getParentId(), job.getDepartmentKind(), job.getTimeZoneStr());
				break;
			case DELETENODE:
				// KKORNEL: AES-17638 - Moved to a function
				result = ntm.deleteNode(nodeManager, job.getNodeId());
				break;
			case MOVENODE:
				sm.openTransaction();
				if (job.getNodeId() == null || job.getParentId() == null) {
					throw new Exception("Missing id (parent or node)!");
				}
				result = nodeManager.moveNode(job.getNodeId(), job.getParentId());
				sm.commitTransaction();
				break;
			case GETENTERPRISE: 
				result = nodeManager.getEnterprise();
				break;
			case GETCONTAINRULES:
				NodeContainRules containRules = new NodeContainRules();
				
				Node node = sm.get(Node.class, job.getNodeId());
				
				List<String> nameList = new ArrayList<String>();
				for (Class c : containRules.getChildrenList(node.getClass())) {
					nameList.add(c.getCanonicalName());
				}
				result = AvailableNodeResult.newInstance(nameList);
				sm.commitTransaction();
				break;
			case GETALL:
				List<Node> nodes = sm.execute("FROM Node WHERE level=0").list();
				for(Node n : nodes){
					nodeManager.listChildren(n, 0);
				}
				result = new ArrayList<Node>(nodes);
				sm.commitTransaction();
				break;
			case SAVENODE:
				// KKORNEL: AES-17638 - Moved to a function
				ntm.saveNode((Node) object, job.getModuleDepartment().getId());
				break;
			case GETNODEFOREDIT:
				result = DomainManager.buildDomain((Serializable)job.getRequest(), job.getModuleDepartment());
				//result = nodeManager.getNodeWithEditableProperties(job.getNodeId());
				break;
			case GETCONTRACTS:
				result = DomainManager.buildDomain((Serializable)job.getRequest(), job.getModuleDepartment());
				break;
			case GETCONTRACT:
				result = DomainManager.buildDomain((Serializable)job.getRequest(), job.getModuleDepartment());
				break;
			case SAVECONTRACT:
				// KKORNEL: AES-8396 - ModuleAuditTrail property added
				result = DomainCommitterManager.commitDomain((RADBean)object, job.getModuleDepartment(), job.getModuleAuditTrail());
				break;
			case SAVENODEADDRESS : {
				// KKORNEL: AES-17638 - Moved to a function
				ntm.saveNodeAddresses(job.getNodeAddresses());
				break;
	
			}
			case GETALLCONTRAT: {
				result = DomainManager.buildDomain((Serializable)job.getRequest(), job.getModuleDepartment());
				break;
			}
			// KKORNEL: AES-9455
			case IS_ADDRESS_ASSOCIATED_TO_PO: {
				Boolean isAssociated = (job.getAddressId() != null) && 
					(sm.execute("SELECT po.id " +
							   "FROM PurchaseOrder po " +
							   "LEFT JOIN po.billTo bt " +
							   "LEFT JOIN po.shipTo st " +
							   "WHERE (bt.id = :addressId) OR (st.id = :addressId)")
					  .setLong("addressId", job.getAddressId())
					  .setMaxResults(1).uniqueResult() != null);
				return isAssociated;
			}
			}
			
		
			
		}
		catch (Exception e) {
			log.error("",e);
			throw e;
		}
		finally {
			sm.closeSession();
		}
		return result;
	}
	
}
